    NAME OsScreen

; This is Os.Screen.Asm.

; If screenType = 0; then this is for a Hercules display.
; If screenType = 1; then this is for a GRiD286 (AT&T mode) display.
; If screenType = 2; then this is for a Toshiba 3100 display.

; NOTE: The AT&T and Toshiba displays are almost identical


CGROUP GROUP CODE

EXTRN  font8x16: NEAR

PUBLIC screenSeg

PUBLIC CpAddrOfSystemFont
PUBLIC SetScreenMode
PUBLIC CpScreenInfo
PUBLIC CpScreenInfoNear

PUBLIC emsBase

gridCaseAspect EQU 105 ; aspect of 100 will bring out bug in GPaint
herculesAspect EQU 145
toshibaAspect  EQU 120

%IF (%screenType EQ 0) THEN (
screenSeg EQU 0B000H
) FI

%IF (%screenType EQ 1 OR %screenType EQ 2) THEN (
screenSeg EQU 0B800H
) FI


CODE SEGMENT PUBLIC 'CODE'
  ASSUME CS:CGROUP


emsBase DW 0FFFFH          ; Init to -1 to flag that it isn't set yet


;   CpAddrOfSystemFont
;
;  This routine returns a pointer to the built-in system font
;

CpAddrOfSystemFont PROC FAR
  PUSH CS
  POP  ES
  MOV  BX, OFFSET font8x16
  RET
CpAddrOfSystemFont ENDP
$EJECT

;   SetScreenMode: PROCEDURE CLEAN;
;
;  This routine will set the screen to Hercules Graphics mode
;

%IF (%screenType EQ 0) THEN (
gTable    DB 35h, 2dh, 2eh, 07h, 5bh, 02h, 57h, 57h, 02h, 03h, 00h, 00h
) FI

SetScreenMode PROC FAR
  PUSH DS
  PUSH BP
  CMP  CS:emsBase, 0FFFFH
  JNE  SetScrModeEmsBaseSet

  INT  71H                    ; Call to Cp Module
  DB   58H                    ; EmsStartAddress
  MOV  CS:emsBase, AX

SetScrModeEmsBaseSet:
%IF (%screenType EQ 1) THEN (
  MOV  AX, 40H
  INT  10H
) FI

%IF (%screenType EQ 2) THEN (
  MOV  AX, 74H
  INT  10H
) FI

%IF (%screenType EQ 0) THEN (
; Clear direction for LODSB & SETW below
  CLD

; Allow setting of graphics mode
  MOV  AL, 1
  MOV  DX, 3BFH     ; Hercules Configuration Switch
  OUT  DX, AL

; Change mode to graphics but without screen display enabled
  MOV  AL, 2
  MOV  DX, 3B8H
  OUT  DX, AL

; Initialize the 6845
  MOV  AX, CS
  MOV  DS, AX
  MOV  SI, OFFSET CGROUP:gTable

  MOV  DX, 3B4H
  MOV  CX, 12
; CLD               ; (Done above)
  XOR  AH, AH

Parms:
  MOV  AL, AH
  OUT  DX, AL
  INC  DX
  LODSB
  OUT  DX, AL
  INC  AH           ; next value
  DEC  DX
  LOOP Parms

; Clear the display buffer
  MOV  CX, 04000H
  MOV  AX, screenSeg
  MOV  ES, AX
  XOR  DI, DI
  XOR  AX, AX
; CLD               ; (Done above)
  REP  STOSW

; Turn screen on in graphics mode, page 0
  MOV  DX, 3B8H
  MOV  AL, 10
  OUT  DX, AL
) FI

  POP   BP
  POP   DS
  RET
SetScreenMode ENDP  
$EJECT

;    CpScreenInfo : PROCEDURE (pInfo) CLEAN;
;      DCL pInfo     PTR;
;      DCL info      BASED pInfo  ScreenInfoType;
;
;    This will return information about screen size, etc.

; NOTE: The yAspect value has to be divisible down to a small fraction to
;       be usable by GPlan2 and GPaint.  Values that are known to work are
;       100 (obviously), 140 and 120.  The smallest known value to work on
;       a 640xnnn display is 105.  DO NOT USE 100 unless GPaint is rereleased.
; AND...Do not ever use a yAspect value of 100.  This is because of a bug in
;       GPaint.  It assumes that the machine that it is running on is a
;       Compass (w/ screen mode = grid mode) whenever aspect is 100.

ScreenInfoType STRUC
  xPixels    DW ?
  yPixels    DW ?
  pScreenOff DW ?
  pScreenSeg DW ?
  bitsPerPel DB ?
  yAspect    DW ?
ScreenInfoType ENDS

screenInfo   EQU ES:[DI]
pScreenInfo  EQU DWORD PTR [BP+6]

CpScreenInfo PROC FAR
CpScreenInfoNear LABEL NEAR
  PUSH BP
  MOV  BP, SP

  LES  DI, pScreenInfo

%IF (%screenType EQ 0) THEN (
  MOV  screenInfo.xPixels, 720
  MOV  screenInfo.yPixels, 348
  MOV  screenInfo.yAspect, herculesAspect
) FI

%IF (%screenType EQ 1) THEN (
  MOV  screenInfo.xPixels, 640
  MOV  screenInfo.yPixels, 400
  MOV  screenInfo.yAspect, gridcaseAspect
) FI

%IF (%screenType EQ 2) THEN (
  MOV  screenInfo.xPixels, 640
  MOV  screenInfo.yPixels, 400
  MOV  screenInfo.yAspect, toshibaAspect
) FI

  MOV  screenInfo.pScreenSeg, screenSeg
  MOV  screenInfo.pScreenOff, 0
  MOV  screenInfo.bitsPerPel, 1

  POP  BP
  RET  4
CpScreenInfo ENDP

PURGE screenInfo
PURGE pScreenInfo
PURGE ScreenInfoType
PURGE xPixels
PURGE yPixels
PURGE pScreenOff
PURGE pScreenSeg
PURGE bitsPerPel
PURGE yAspect


CODE ENDS

    END
